package cn.waka.sys.admin.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Component;

import cn.waka.sys.admin.object.Node;

@Component
public class NodeDao extends BaseDao {
    public List<String> findAllURI() {
        String sql = "select node from s_system_node where is_auth=1";
        List<String> list = this.query(sql, new RowMapper<String>() {

            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {

                String s = rs.getString(1);
                if (!s.startsWith("/")) {
                    s = "/" + s;
                }
                return s;
            }

        });

        return list;
    }

    public List<Node> findAll() {
        String sql = "select id,node,title from s_system_node where is_auth=1";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                return n;
            }

        });

        return list;
    }

    /*
     *
     */
    public List<Node> findByRoleId(int authId) {
        String sql = "select n.id,n.node,n.title from s_system_auth_node an left join s_system_node n on an.node_id=n.id where an.auth=?";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                return n;
            }

        }, authId);

        return list;
    }

    public int save(final Node node) {
        KeyHolder holder = new GeneratedKeyHolder();
        this.update(new PreparedStatementCreator() {

            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                String sql = "INSERT INTO s_system_node(node,title,create_at,pid,is_auth,is_menu)VALUES(?,?,?,?,1,0)";
                PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                ps.setString(1, node.getNode());
                ps.setString(2, node.getTitle());
                ps.setTimestamp(3, node.getCreateAt());
                ps.setInt(4, node.getPid());
                return ps;
            }
        }, holder);
        int id = holder.getKey().intValue();
        return id;
    }

    public List<Node> getSelectNode() {
        String sql = "select id,node,title,pid from s_system_node WHERE is_menu=1 and pid = 0";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                n.setPid(rs.getInt(4));
                n.setChildren(getSelectChildren(rs.getInt(1)));
                return n;
            }
        });

        return list;
    }

    public List<Node> getSelectChildren(int pid) {
        String sql = "select id,node,title,is_menu,is_auth,pid from s_system_node WHERE pid=? and is_menu=1";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                n.setPid(rs.getInt(6));

                return n;
            }

        }, pid);

        return list;
    }

    //获取父节点
    public List<Node> getNodeList() {
        String sql = "select id,node,title,is_menu,is_auth,pid from s_system_node WHERE pid=0";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                int is_menu = rs.getInt(4);
                if (is_menu == 1) {
                    n.setMenu(true);
                } else {
                    n.setMenu(false);
                }
                int is_auth = rs.getInt(5);
                if (is_auth == 1) {
                    n.setAuth(true);
                } else {
                    n.setAuth(false);
                }
                n.setPid(rs.getInt(6));
                n.setChildren(getChildrenList(rs.getInt(1)));
                return n;
            }
        });

        return list;
    }

    //获取子节点
    public List<Node> getChildrenList(int pid) {
        String sql = "select id,node,title,is_menu,is_auth,pid from s_system_node WHERE pid=?";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                int is_menu = rs.getInt(4);
                if (is_menu == 1) {
                    n.setMenu(true);
                } else {
                    n.setMenu(false);
                }
                int is_auth = rs.getInt(5);
                if (is_auth == 1) {
                    n.setAuth(true);
                } else {
                    n.setAuth(false);
                }
                n.setPid(rs.getInt(6));

                return n;
            }

        }, pid);

        return list;
    }

    public Node getNodeById(int id) {
        String sql = "select id,node,title,is_menu,is_auth,pid from s_system_node WHERE id=?";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                int is_menu = rs.getInt(4);
                if (is_menu == 1) {
                    n.setMenu(true);
                } else {
                    n.setMenu(false);
                }
                int is_auth = rs.getInt(5);
                if (is_auth == 1) {
                    n.setAuth(true);
                } else {
                    n.setAuth(false);
                }
                n.setPid(rs.getInt(6));

                return n;
            }

        }, id);
        return list.size() > 0 ? list.get(0) : null;
    }

    public Node getNodeByUrl(String node) {
        String sql = "select id,node,title,is_menu,is_auth,pid from s_system_node WHERE node = ?";
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setNode(rs.getString(2));
                n.setTitle(rs.getString(3));
                int is_menu = rs.getInt(4);
                if (is_menu == 1) {
                    n.setMenu(true);
                } else {
                    n.setMenu(false);
                }
                int is_auth = rs.getInt(5);
                if (is_auth == 1) {
                    n.setAuth(true);
                } else {
                    n.setAuth(false);
                }
                n.setPid(rs.getInt(6));

                return n;
            }

        }, node);
        return list.size() > 0 ? list.get(0) : null;
    }

    public int update(Node node) {
        int r = this.update("update s_system_node set title=?,is_auth=?,is_menu=?,pid=? where id=?", node.getTitle(), node.isAuth(), node.isMenu(), node.getPid(), node.getId());
        return r;
    }

    public List<Node> getNodeTree(int role_id) {
        String sql = "SELECT n.id,n.title,n.`node`,n.`pid`,an.auth FROM  `s_system_node` n LEFT JOIN `s_system_auth_node` an ON n.id=an.node AND an.`auth`=? WHERE n.`is_auth`=1";
        final Map<Integer, Node> msAll = new LinkedHashMap<Integer, Node>();
        List<Node> list = this.query(sql, new RowMapper<Node>() {

            @Override
            public Node mapRow(ResultSet rs, int rowNum) throws SQLException {
                Node n = new Node();
                n.setId(rs.getInt(1));
                n.setTitle(rs.getString(2));
                n.setNode(rs.getString(3));
                n.setPid(rs.getInt(4));
                if (rs.getString(5) != null) {
                    n.setChecked(true);
                } else {
                    n.setChecked(false);
                }
                msAll.put(rs.getInt(1), n);
                return n;
            }
        }, role_id);

        Node top = new Node();
        top.setId(0);
        top.setTitle("顶级节点");
        top.setNode("顶级节点");
        top.setPid(-1);
        top.setChecked(true);
        msAll.put(0, top);

        List<Node> ms = new ArrayList<Node>();
        for (Node m : msAll.values()) {
            if (m.getPid() == -1) {
                ms.add(m);
            } else {
                msAll.get(m.getPid()).add(m);
            }
        }

        return ms;
    }

    public int delAll(String role_id) {
        int r = this.update("delete from s_system_auth_node where auth=?", role_id);
        return r;
    }

    public int insertAuthNode(String role_id, String node) {
        KeyHolder holder = new GeneratedKeyHolder();
        this.update(new PreparedStatementCreator() {

            @Override
            public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                String sql = "INSERT INTO s_system_auth_node(auth,node)VALUES(?,?)";
                PreparedStatement ps = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                ps.setInt(1, Integer.parseInt(role_id));
                ps.setString(2, node);
                return ps;
            }
        }, holder);
        return 1;
    }

}
